#include "bme280_application.h"

/*
In file in bme280_defs.h
In case of the macro "BME280_FLOAT_ENABLE" enabled, The outputs are in double and the units are

- Celsius for temperature
- % relative humidity
- Pascal for pressure
In case if "BME280_FLOAT_ENABLE" is not enabled, then it is

- int32_t for temperature with the units 100 * Celsius
- uint32_t for humidity with the units 1024 * % relative humidity
- uint32_t for pressure
     If macro "BME280_64BIT_ENABLE" is enabled, which it is by default, the unit is 100 * Pascal
     If this macro is disabled, Then the unit is in Pascal
*/

//struct bme280_data comp_data = {0.0f, 0.0f, 0.0f};

//void BME280_INIT()
//{
//	uint32_t bme280_count = 0;
//struct bme280_dev dev;
//int8_t rslt = BME280_OK;

//dev.dev_id = BME280_I2C_ADDR_PRIM;
//dev.intf = BME280_I2C_INTF;
//dev.read = user_i2c_read;
//dev.write = user_i2c_write;
//dev.delay_ms = user_delay_ms;

//rslt = bme280_init(&dev);
//}


/**
 * @function: int8_t stream_sensor_data_normal_mode(struct bme280_dev *dev)
 * @description: 正常模式获取数据
 * @param {structbme280_dev} *dev
 * @return {*}
 */
int8_t stream_sensor_data_normal_mode(struct bme280_dev *dev)
{
  int8_t rslt;
  uint8_t settings_sel;
  // struct bme280_data comp_data;

  /* Recommended mode of operation: Indoor navigation */
  dev->settings.osr_h = BME280_OVERSAMPLING_1X;
  dev->settings.osr_p = BME280_OVERSAMPLING_16X;
  dev->settings.osr_t = BME280_OVERSAMPLING_2X;
  dev->settings.filter = BME280_FILTER_COEFF_16;
  dev->settings.standby_time = BME280_STANDBY_TIME_62_5_MS;

  settings_sel = BME280_OSR_PRESS_SEL;
  settings_sel |= BME280_OSR_TEMP_SEL;
  settings_sel |= BME280_OSR_HUM_SEL;
  settings_sel |= BME280_STANDBY_SEL;
  settings_sel |= BME280_FILTER_SEL;
  rslt = bme280_set_sensor_settings(settings_sel, dev);
  // bme280_set_sensor_settings(settings_sel, dev);
  rslt = bme280_set_sensor_mode(BME280_NORMAL_MODE, dev);
  // bme280_set_sensor_mode(BME280_NORMAL_MODE, dev);

  // printf("Temperature           Pressure             Humidity\r\n");

  // uint32_t count = 0;
  // while (1)
  {
    /* Delay while the sensor completes a measurement */
    dev->delay_ms(70);
    rslt = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
    // bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
    //print_sensor_data(&comp_data);
    // printf("%ld-Temperature:%.2fC  Pressure:%.2fkPa   Humidity:%.2f%%\r\n", count++, comp_data.temperature, comp_data.pressure / 1000, comp_data.humidity);
  }
  return rslt;
}

/**
 * @function: int8_t stream_sensor_data_forced_mode(struct bme280_dev *dev)
 * @description: 强制模式获取数据
 * @param {structbme280_dev} *dev
 * @return {*}
 */
int8_t stream_sensor_data_forced_mode(struct bme280_dev *dev)
{
  int8_t rslt;
  uint8_t settings_sel;
  // struct bme280_data comp_data;

  /* Recommended mode of operation: Indoor navigation */
  dev->settings.osr_h = BME280_OVERSAMPLING_1X;
  dev->settings.osr_p = BME280_OVERSAMPLING_16X;
  dev->settings.osr_t = BME280_OVERSAMPLING_2X;
  dev->settings.filter = BME280_FILTER_COEFF_16;

  settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL | BME280_OSR_HUM_SEL | BME280_FILTER_SEL;

  rslt = bme280_set_sensor_settings(settings_sel, dev);
  // bme280_set_sensor_settings(settings_sel, dev);

  // printf("Temperature           Pressure             Humidity\r\n");
  /* Continuously stream sensor data */
  // while (1)
  {
    rslt = bme280_set_sensor_mode(BME280_FORCED_MODE, dev);
    // bme280_set_sensor_mode(BME280_FORCED_MODE, dev);
    /* Wait for the measurement to complete and print data @25Hz */
    dev->delay_ms(40);
    rslt = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
    // bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
    // print_sensor_data(&comp_data);
  }
  return rslt;
}

/**********************通讯接口读写**************************/
/**
 * @function: void user_delay_ms(uint32_t period)
 * @description: 用户自定义ms延时
 * @param {uint32_t} period 延时时间(ms)
 * @return {*}
 */
void user_delay_ms(uint32_t period)
{
  HAL_Delay(period);
}

/**
 * @function: int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
 * @description: i2c读函数
 * @param {uint8_t} dev_id 器件地址
 * @param {uint8_t} reg_addr 器件寄存器地址
 * @param {uint8_t} *reg_data 读取的寄存器数据
 * @param {uint16_t} len 读取数据长度
 * @return {0} 读取成功
 * @return {-1} 读取失败
 */
int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
{
#if BME280_USING_HARDWARE_I2C
  int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
  HAL_StatusTypeDef status = HAL_OK;
  status = HAL_I2C_Mem_Read(&I2Cx, dev_id, reg_addr, I2C_MEMADD_SIZE_8BIT, reg_data, len, 0xffff);
  if (status == HAL_OK)
  {
    rslt = 0;
  }
  else
  {
    rslt = -1;
  }
  return rslt;
#endif
#if BME280_USING_SOFTWARE_I2C
  Software_I2C_Start();
  Software_I2C_WriteByte(dev_id & 0xFE); //写入器件地址(写)
  if (Software_I2C_WaitACK())
    return -1;
  Software_I2C_WriteByte(reg_addr); //写入寄存器地址
  // if (Software_I2C_WaitACK())
  //   return -1;
  Software_I2C_WaitACK();
  Software_I2C_Start();                  //restart
  Software_I2C_WriteByte(dev_id | 0x01); //写入器件地址(读)
  // if (Software_I2C_WaitACK())
  // return -1;
  Software_I2C_WaitACK();
  while (len--)
  {
    *reg_data = Software_I2C_ReadByte(); //读取数据
    Software_I2C_ACK();
    reg_data++;
  }
  Software_I2C_NACK();
  Software_I2C_Stop();
  return 0;
#endif
}

/**
 * @function: int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
 * @description: i2c写函数
 * @param {uint8_t} dev_id 器件地址
 * @param {uint8_t} reg_addr 器件寄存器地址
 * @param {uint8_t} *reg_data 写入寄存器的数据
 * @param {uint16_t} len 读取数据长度
 * @return {0} 读取成功
 * @return {-1} 读取失败
 */
int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
{
#if BME280_USING_HARDWARE_I2C
  int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
  HAL_StatusTypeDef status = HAL_OK;
  status = HAL_I2C_Mem_Write(&I2Cx, dev_id, reg_addr, I2C_MEMADD_SIZE_8BIT, reg_data, len, 0xffff);

  if (status == HAL_OK)
  {
    rslt = 0;
  }
  else
  {
    rslt = -1;
  }
  return rslt;
#endif
#if BME280_USING_SOFTWARE_I2C
  Software_I2C_Start();
  Software_I2C_WriteByte(dev_id & 0xFE); //写器件地址(写)
  if (Software_I2C_WaitACK())
    return -1;
  while (len--)
  {
    Software_I2C_WriteByte(reg_addr); //写入寄存器地址(不自增)`
    // if (Software_I2C_WaitACK())
    //   return -1;
    Software_I2C_WaitACK();
    Software_I2C_WriteByte(*reg_data); //写入数据
    // if (Software_I2C_WaitACK())
    // return -1;
    Software_I2C_WaitACK();
    // reg_addr++;
    reg_data++;
  }
  Software_I2C_Stop();
  return 0;
#endif
}
